Friend Class TabView
    Inherits FlickerFreeControl

#Region "Construction"
    Const MaxWidth As Integer = 250
    Const MinWidth As Integer = 90

    Friend WithEvents Pages As PageCollection

    Private WithEvents DropdownButton As DropdownButton

    Public Sub New(ByVal parent As PageCollection)
        Me.Pages = parent
        Me.Dock = DockStyle.Top
        Me.Height = 25
        parent.Controls.Add(Me)
        Me.DropdownButton = New DropdownButton(Me)
        Me.SendToBack()
    End Sub
#End Region

#Region "Resize Logic"
    Private leftMostVisibleIndex As Integer = 0

    Private Function GetVisibleTabs() As Control()
        If (Pages.Count = 0) Then Return New TabPageControl() {}

        Dim numVisibleTabs As Integer = Math.Max(1, Math.Min(Me.Width / MinWidth, Pages.Count))
        Dim currentIndex As Integer = Pages.IndexOf(Pages.CurrentPage)

        Me.DropdownButton.Visible = numVisibleTabs < Pages.Count

        leftMostVisibleIndex = Math.Min(leftMostVisibleIndex, Pages.Count - numVisibleTabs)
        If (currentIndex < leftMostVisibleIndex) Then
            leftMostVisibleIndex = Math.Min(currentIndex, Pages.Count - 1 - numVisibleTabs)
        ElseIf (currentIndex >= leftMostVisibleIndex + numVisibleTabs) Then
            leftMostVisibleIndex = Math.Max(currentIndex - numVisibleTabs + 1, 0)
        End If

        Dim controls() As Control
        Dim tabWidth As Integer
        Dim tabLeft As Integer
        Dim i As Integer

        If (Me.DropdownButton.Visible) Then
            ReDim controls(numVisibleTabs)
            Me.DropdownButton.Height = Me.Height
            controls(0) = Me.DropdownButton
            tabWidth = Math.Min(MaxWidth, (Me.Width - Me.DropdownButton.Width) / numVisibleTabs)
            tabLeft = Me.DropdownButton.Width
            i = 1
        Else
            ReDim controls(numVisibleTabs - 1)
            tabWidth = Math.Min(MaxWidth, Me.Width / numVisibleTabs)
            tabLeft = 0
            i = 0
        End If

        Dim totalWidth As Integer = tabLeft
        Dim ctl As Control = Nothing
        Dim j As Integer = 0

        While (i < controls.Length)
            ctl = Pages.Item(leftMostVisibleIndex + j).TabPageCtl
            controls(i) = ctl
            ctl.Location = New Point(tabLeft, 0)
            ctl.Size = New Size(tabWidth, Me.Height)
            ctl.Visible = True

            tabLeft += tabWidth
            totalWidth += tabWidth
            i += 1
            j += 1
        End While

        ctl.Width = Math.Min(ctl.Width + Me.Width - ctl.Right, MaxWidth)

        Return controls
    End Function

    Private Sub RefreshTabs()
        Me.SuspendPainting = True
        Me.Controls.Clear()
        Me.Controls.AddRange(GetVisibleTabs())
        Me.SuspendPainting = False
    End Sub

    Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
        MyBase.OnResize(e)
        Me.RefreshTabs()
    End Sub
#End Region

#Region "Page Events"
    Private Sub MyParent_CurrentPageChanged(ByVal currentPage As TabPage, ByVal previousPage As TabPage) Handles Pages.CurrentPageChanged
        Me.SuspendPainting = True
        If (currentPage IsNot Nothing) Then currentPage.TabPageCtl.IsCurrent = True
        If (previousPage IsNot Nothing) Then previousPage.TabPageCtl.IsCurrent = False
        Me.RefreshTabs()
        Me.SuspendPainting = False
    End Sub

    Private Sub MyParent_PageAdded(ByVal page As TabPage) Handles Pages.PageAdded
        page.TabPageCtl.Width = MaxWidth
        Me.RefreshTabs()
    End Sub

    Private Sub MyParent_PageRemoved(ByVal page As TabPage) Handles Pages.PageRemoved
        Me.RefreshTabs()
    End Sub
#End Region

#Region "Rendering"
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        If (Me.Pages Is Nothing) Then Exit Sub

        Dim totalWidth As Integer = 0
        For Each ctl As Control In Me.Controls
            totalWidth += ctl.Width
        Next

        Using borderPen As Pen = TabBaseControl.GetBorderPen(Me.Pages.TabColor)
            e.Graphics.DrawLine(borderPen, totalWidth, Me.Height - 1, Me.Width, Me.Height - 1)
        End Using
    End Sub
#End Region

End Class